<template>
    <view v-if="showPopup" class="uni-popup" @touchmove.stop.prevent="clear">
        <uni-transition
            :mode-class="['fade']"
            :styles="maskClass"
            :duration="duration"
            :show="showTrans"
            @tap="onTap"
        />
        <uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @tap="onTap">
            <view class="uni-popup__wrapper-box" @tap.stop="clear">
                <slot />
            </view>
        </uni-transition>
    </view>
</template>

<script>
import uniTransition from "../uni-transition/uni-transition.vue";

/**
 * PopUp 弹出层
 * @description 弹出层组件，为了解决遮罩弹层的问题
 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
 * @property {String} type = [top|center|bottom] 弹出方式
 * 	@value top 顶部弹出
 * 	@value center 中间弹出
 * 	@value bottom 底部弹出
 * @property {Boolean} animation = [ture|false] 是否开启动画
 * @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
 * @event {Function} change 打开关闭弹窗触发，e={show: false}
 */

export default {
    name: "UniPopup",
    components: {
        uniTransition,
    },
    props: {
        // 开启动画
        animation: {
            type: Boolean,
            default: true,
        },
        // 弹出层类型，可选值，top: 顶部弹出层；bottom：底部弹出层；center：全屏弹出层
        type: {
            type: String,
            default: "center",
        },
        // maskClick
        maskClick: {
            type: Boolean,
            default: true,
        },
    },
    data() {
        return {
            duration: 300,
            ani: [],
            showPopup: false,
            showTrans: false,
            maskClass: {
                position: "fixed",
                bottom: 0,
                top: 0,
                left: 0,
                right: 0,
                backgroundColor: "rgba(0, 0, 0, 0.3)",
            },
            transClass: {
                position: "fixed",
                left: 0,
                right: 0,
            },
        };
    },
    watch: {
        type: {
            handler: function (newVal) {
                switch (this.type) {
                    case "top":
                        this.ani = ["slide-top"];
                        this.transClass = {
                            position: "fixed",
                            left: 0,
                            right: 0,
                        };
                        break;
                    case "bottom":
                        this.ani = ["slide-bottom"];
                        this.transClass = {
                            position: "fixed",
                            left: 0,
                            right: 0,
                            bottom: 0,
                        };
                        break;
                    case "center":
                        this.ani = ["zoom-out", "fade"];
                        this.transClass = {
                            position: "fixed",
                            /* #ifndef APP-NVUE */
                            display: "flex",
                            flexDirection: "column",
                            /* #endif */
                            bottom: 0,
                            left: 0,
                            right: 0,
                            top: 0,
                            justifyContent: "center",
                            alignItems: "center",
                        };

                        break;
                }
            },
            immediate: true,
        },
    },
    created() {
        if (this.animation) {
            this.duration = 300;
        } else {
            this.duration = 0;
        }
    },
    methods: {
        clear(e) {
            // TODO nvue 取消冒泡
            e.stopPropagation();
        },
        open() {
            this.showPopup = true;
            this.$nextTick(() => {
                clearTimeout(this.timer);
                this.timer = setTimeout(() => {
                    this.showTrans = true;
                }, 50);
            });
            this.$emit("change", {
                show: true,
            });
        },
        close(type) {
            this.showTrans = false;
            this.$nextTick(() => {
                clearTimeout(this.timer);
                this.timer = setTimeout(() => {
                    this.$emit("change", {
                        show: false,
                    });
                    this.showPopup = false;
                }, 300);
            });
        },
        onTap() {
            if (!this.maskClick) return;
            this.close();
        },
    },
};
</script>
<style scoped>
.uni-popup {
    position: fixed;
    /* #ifdef H5 */
    top: var(--window-top);
    /* #endif */
    /* #ifndef H5 */
    top: 0;
    /* #endif */
    bottom: 0;
    left: 0;
    right: 0;
    /* #ifndef APP-NVUE */
    z-index: 99;
    /* #endif */
}

.uni-popup__mask {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: rgba(0, 0, 0, 0.4);
    opacity: 0;
}

.mask-ani {
    transition-property: opacity;
    transition-duration: 0.2s;
}

.uni-top-mask {
    opacity: 1;
}

.uni-bottom-mask {
    opacity: 1;
}

.uni-center-mask {
    opacity: 1;
}

.uni-popup__wrapper {
    /* #ifndef APP-NVUE */
    display: block;
    /* #endif */
    position: absolute;
}

.top {
    top: 0;
    left: 0;
    right: 0;
    transform: translateY(-500px);
}

.bottom {
    bottom: 0;
    left: 0;
    right: 0;
    transform: translateY(500px);
}

.center {
    /* #ifndef APP-NVUE */
    display: flex;
    flex-direction: column;
    /* #endif */
    bottom: 0;
    left: 0;
    right: 0;
    top: 0;
    justify-content: center;
    align-items: center;
    transform: scale(1.2);
    opacity: 0;
}

.uni-popup__wrapper-box {
    /* #ifndef APP-NVUE */
    display: block;
    /* #endif */
    position: relative;
}

.content-ani {
    /* transition: transform 0.3s;
 */
    transition-property: transform, opacity;
    transition-duration: 0.2s;
}

.uni-top-content {
    transform: translateY(0);
}

.uni-bottom-content {
    transform: translateY(0);
}

.uni-center-content {
    transform: scale(1);
    opacity: 1;
}
</style>
